/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package vta.core

import chisel3._
import chisel3.util._

/** ISAConstants.
  *
  * These constants are used for decoding (parsing) fields on instructions.
  */
trait ISAConstants
{
   val INST_BITS = 128

   val OP_BITS = 3

   val M_DEP_BITS = 4
   val M_ID_BITS = 2
   val M_SRAM_OFFSET_BITS = 16
   val M_DRAM_OFFSET_BITS = 32
   val M_SIZE_BITS = 16
   val M_STRIDE_BITS = 16
   val M_PAD_BITS = 4

   val C_UOP_BGN_BITS = 13
   val C_UOP_END_BITS = 14
   val C_ITER_BITS = 14
   val C_AIDX_BITS = 11
   val C_IIDX_BITS = 11
   val C_WIDX_BITS = 10
   val C_ALU_DEC_BITS = 2 // FIXME: there should be a SHL and SHR instruction
   val C_ALU_OP_BITS = 3
   val C_ALU_IMM_BITS = 16

   val Y = true.B
   val N = false.B

   val OP_L = 0.asUInt(OP_BITS.W)
   val OP_S = 1.asUInt(OP_BITS.W)
   val OP_G = 2.asUInt(OP_BITS.W)
   val OP_F = 3.asUInt(OP_BITS.W)
   val OP_A = 4.asUInt(OP_BITS.W)
   val OP_X = 5.asUInt(OP_BITS.W)

   val ALU_OP_NUM = 5
   val ALU_OP = Enum(ALU_OP_NUM)

   val M_ID_U = 0.asUInt(M_ID_BITS.W)
   val M_ID_W = 1.asUInt(M_ID_BITS.W)
   val M_ID_I = 2.asUInt(M_ID_BITS.W)
   val M_ID_A = 3.asUInt(M_ID_BITS.W)
}

/** ISA.
  *
  * This is the VTA ISA, here we specify the cares and dont-cares that makes
  * decoding easier. Since instructions are quite long 128-bit, we could generate
  * these based on ISAConstants.
  *
  * FIXME: VSHX should be replaced by VSHR and VSHL once we modify the compiler
  * TODO: Add VXOR to clear accumulator
  */
object ISA {
  def LUOP = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_???????0_0????000")
  def LWGT = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_???????0_1????000")
  def LINP = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_???????1_0????000")
  def LACC = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_???????1_1????000")
  def SOUT = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????001")
  def GEMM = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????010")
  def VMIN = BitPat("b_????????_????????_??00????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????100")
  def VMAX = BitPat("b_????????_????????_??01????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????100")
  def VADD = BitPat("b_????????_????????_??10????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????100")
  def VSHX = BitPat("b_????????_????????_??11????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????100")
  def FNSH = BitPat("b_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_????????_?????011")
}
